package com.opass.boot.core.model;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.util.Map;

/**
 * 分页查询类
 *
 * @author liuyau
 * @date 2018/07/10
 */
@Data
@ApiModel("分页查询参数")
@JsonIgnoreProperties(ignoreUnknown = true)
public class PageQuery extends  Page implements Serializable {

    private static final long serialVersionUID = -1710273706052960025L;
    /**
     * 默认最小页码
     */
    public static final int MIN_PAGE = 0;
    /**
     * 最大显示条数
     */
    public static final int MAX_LIMIT = 1000;
    /**
     * 默认页码
     */
    public static final int DEFAULT_PAGE = 1;
    /**
     * 默认显示条数
     */
    public static final int DEFAULT_LIMIT = 10;

    public static final String PAGE_KEY = "page";
    public static final String PAGE_LIMIT_KEY = "limit";
    public static final String PAGE_ASC_KEY = "asc";
    public static final String PAGE_DESC_KEY = "desc";

    @ApiModelProperty(value = "当前页")
    private Integer page = DEFAULT_PAGE;

    @ApiModelProperty(value = "显示条数")
    private Integer limit = DEFAULT_LIMIT;

    @ApiModelProperty(value = "显示条数")
    private String asc;

    @ApiModelProperty(value = "显示条数")
    private String desc;

    /**
     * 其他参数
     */
    @ApiModelProperty(value = "显其参数")
    @JSONField(serialize = false)
    @JsonIgnore
    private JSONObject params = new JSONObject();

    /**
     * 过滤sql
     *
     * @param param
     * @return
     */
    public static String filter(String param) {
        return param == null ? null : param.replaceAll("(?i)'|%|--|insert|delete|select|count|group|union|drop|truncate|alter|grant|execute|exec|xp_cmdshell|call|declare|sql", "");
    }

    public PageQuery() {
        params = new JSONObject();
    }


    public PageQuery(Map map) {
        this(Integer.parseInt(map.getOrDefault(PAGE_KEY, DEFAULT_PAGE).toString()),
                Integer.parseInt(map.getOrDefault(PAGE_LIMIT_KEY, DEFAULT_LIMIT).toString()),
                (String) map.getOrDefault(PAGE_ASC_KEY, ""),
                (String) map.getOrDefault(PAGE_DESC_KEY, ""),
                map);
    }

    public PageQuery(int current, int size) {
        this(current, size, "", "", null);
    }

    public PageQuery(int current, int size, String asc, String desc, Map map) {
        if (current <= MIN_PAGE) {
            current = 1;
        }
        if (size > MAX_LIMIT) {
            size = MAX_LIMIT;
        }
        this.page = current;
        this.limit = size;
        this.asc = asc;
        this.desc = desc;
        if (map == null) {
            map = new JSONObject();
        }
        this.params.putAll(map);
    }

    public <T> T getParams(Class<T> t) {
        return BeanUtil.toBean(this.params, t);
    }

    public JSONObject getParams() {
        return params;
    }

    public void setParams(Map<String, Object> params) {
        this.params.putAll(params);
    }

    public PageQuery put(String key, Object value) {
        this.params.put(key, value);
        return this;
    }

    /**
     * 构建IPage对象
     *
     * @return
     */
    public IPage buildPage() {
        Page page = new Page();
        page.setCurrent(this.getPage());
        page.setSize(this.getLimit());
        page.addOrder(OrderItem.ascs(StringUtils.commaDelimitedListToStringArray(filter(this.getAsc()))));
        page.addOrder(OrderItem.descs(StringUtils.commaDelimitedListToStringArray(filter(this.getDesc()))));
        return page;
    }
}
